Need to push changes from skao-rucio-analysis machine.
Added -u root to cron for prod transfer tasks (otherwise we get a read exception on mounted x509 certificate). This is a result of making the default user in Dockerfile
non-root.
Bug in rucio-analysis using latest client with prod server (at 1.26). Errors with listDIDs "filters" variable (expected behaviour using a newer client with older server). Have changed the break to a continue when adding the file to a dataset. Need to push this change.
Fired off a few admin=False tests for tokens on dev. Seemed to work, but one error in about 14. Possibly due to oidc-agent not renewing certificate, so tried it again for 3h with forced renewal (21/04/22 @ 2:45 for 3h).
Need to add this all to a logs doc.
TL;DR I think it's possible to get this to work using the path in the get_token_for_account_operation function:
This would require another config lookup in fts3.py, e.g. FORCE_USE_OIDC_ACCOUNT (under conveyor section) which is injected in to the FTS3TransferTool instance as
oidc_account. This is normally retrieved from the requests table as the account that requested the transfer in the first place.
Would need to create another Rucio account, e.g. transfer-service, that has the identity SUB: admin_client_id and ISS: ESCAPE. This would have to be the only account with this identity as the function __get_admin_account_for_issuer plucks out the first account with this identity mapping.
Would then need a permissions package that restricts e.g. creating/deleting rule functionality accordingly.
Chat with Rizart:
Hey Rizart - hope you're well. Got a question for you. It's a bit detailed - if you're not familiar with this particular section of the code really don't worry about it, i'll figure it out ...
I've been looking at the different ways a token is requested for an operation, specifically the flow where a token from an IdP's "admin client" is used instead of a user's token i.e. admin=True in get_token_for_account_operation() in oidc.py, AND the requesting account is not the same as that mapped from the identity of the admin client, i.e. rucio server must get a token for the account mapped to the admin client for this issuer. I believe the logic for this scenario is here: https://github.com/rucio/rucio/blob/6e27de4e1894a68a6fdeffd6e703b54590336a3d/lib/rucio/core/oidc.py#L597
If I understand correctly, ln599 enforces that a token exists in the database for the requesting account, and ln604 enforces that the required scopes and audiences are present in this token. The actual token retrieval is on ln631.
On to my question: what are the implications if the checks above were removed (i.e. a user token does not have to exist)? Is this a security issue?
github.com
rucio/oidc.py at 6e27de4e1894a68a6fdeffd6e703b54590336a3d ยท rucio/rucio
Rucio - Scientific Data Management. Contribute to rucio/rucio development by creating an account on GitHub.
ridona
ridona
1:43 PM
Hello Rob
I just took a look, not very familiar with that part indeed, but my take is the following
if no user token exists in the DB, then you cannot really know if the user has been authenticated
so in a way I think that's what it tries to prevent
more generally, this "flow" looks super bizarre
because then why would you need to use the rucio "admin" IAM client to request the token
rbarnsley
rbarnsley
2:57 PM
ah, okay, yes, I think that was the conclusion I was arriving at
yeah, i'm not really sure why this exists then, to be honest
i guess it adds the ability to use a client credentials grant type rather than authorization code, but I don't understand the use case
ridona
ridona
3:09 PM
I think it's just there to support this weird flow, in case for example you have configured the conveyor to not accept user tokens
because that function is connected only with the FTS logic
in practise not really, because since a token already exists, authorisation code grant has been used before
rbarnsley 3:02 PM
i guess it adds the ability to use a client credentials grant type rather than authorization code, but I don't understand the use case
rbarnsley
rbarnsley
3:12 PM
well that's just it, that's the bit I don't understand. this "admin" flow still requires a user token to exist, as you say, having been obtained by authorization code
ridona
ridona
3:12 PM
yeah, it's weird
3:40 PM
in theory, if i remove the checks on the user token above (existence/scope/audience) for this "admin flow", and created a comprehensive permissions package that checks groups on the user's token, do you think that would that allow an autonomous interaction (i.e. no user input required?)
or is that just stupid?
basically moving authZ to rucio
ridona
ridona
3:43 PM
a comprehensive permissions package that checks groups on the user's token -> what do you mean here? which token? I think you assume there is no token available, right?
rbarnsley
rbarnsley
3:48 PM
yes, good point,
i think i mean create a system where the daemons can retrieve the token autonomously via the admin client's mapped account, but a user interacting with rucio cli/api would be subject to some permissions check
but now i type this the more i realise this probably doesn't make sense
ridona
ridona
3:55 PM
hmm
I think this already exists
it should be the:
# <a name="-4" class="markdown-link" id="-4">Rucio admin account requesting OIDC token</a>
if get_token_for_adminacc:
case
but when you say permission check, you mean with the rucio permission modules?
in this case, in theory, no user info is needed
ridona 3:56 PM
it should be the:
# <a name="-5" class="markdown-link" id="-5">Rucio admin account requesting OIDC token</a>
if get_token_for_adminacc:
case
The much talked about "admin token workflow" (admin=True in this function) is not really useful in its current form for us. There are three methods by which rucio currently gets a token:
I think we were (or at least I was) interested in the possibility of using the second of these methods (i.e. interaction being user -> auth -> user token -> request operation -> admin client's mapped account token -> operation) instead of passing user tokens to storage endpoints as a way of simplifying the flow. We would then have to have Rucio handle permissions based on the user token's groups/scopes before the operation is "delegated" to the admin client's mapped account (could be any Rucio account with the right identity attached).
The problem with this, in its current form, is here. A user token must exist in the database already with the required scopes/audiences before the token can be switched to that of the admin client's mapped account, i.e. this "admin" workflow is not autonomous, it requires a user to sign in. Removing these checks would basically be removing the requirement for a user to be authenticated, in which case you'd have to be really certain that your permissions package comprehensively checked all possible api routes.
Trying to understand rucio oidc workflow code.
Trying to understand rucio oidc workflow code.
Trying to understand rucio oidc workflow code.
Got this working. Was missing the activity in conveyor. Also stripped force_oidc_authN_flag in favour of forcing the user to set the correct RUCIO environment variables before running the ansible script (eventually dev will be all tokens, this doesn't work for a mix of x509 and tokens tests but is conceptually a lot simpler and neater).
Meetings. Fixed issue in CI pipeline with mongo tests not always completing.
Got a semi-working version with a bodge (replications not submitting though?).
Changes on skao-rucio-analysis need to be pushed to master and pulled locally. Need to sort out how the token is propagated through. Even if the token is put in the root account directory, it is inserted into the database with the oidc_account from the token. This means that conveyor won't pick it up. install_task_crontab is a bit messy with this force_oidc_authN flag in the job. Remember that tokens go in to different locations (/tmp/root/.rucio_root and /tmp/user/.rucio_user) depending on the login/account!
Disabled functional tests for now as reaper doesn't work (can't delete tokens off storm!).
Need to do address Martin's issue re: integration tests, and also look at dev work for 1.29).
A/L.
Back to functional tests.
Needed to add bit of code to poller to get it to pass oidc_account to FTS3TransferTool instance, see Radu's comment:
Thanks Radu. How do I get the oidc_account sensibly? chunk['account'] from the chunked transfers here?
Radu Carpa 2 days ago
The chunk can have a list of transfers by different accounts. So the sort https://github.com/rucio/rucio/blob/abe3c77ed31b89661a7a13209d58ff3b62e2a266/lib/rucio/daemons/conveyor/poller.py#L99 here and the following two group_by must be adapted to group transfers by account. But then the account is in t['account'] of each transfer
The same as it's done for the 'vo'
Started on integrating functional tests in to RUcio